package dk.mirasola.systemtraining.bridgewidgets.shared.model;


public enum Card  {
    SPADE_ACE(Suit.SPADE, Rang.ACE, 4),
    SPADE_KING(Suit.SPADE, Rang.KING, 3),
    SPADE_QUEEN(Suit.SPADE, Rang.QUEEN, 2),
    SPADE_JACK(Suit.SPADE, Rang.JACK, 1),
    SPADE_TEN(Suit.SPADE, Rang.TEN),
    SPADE_NINE(Suit.SPADE, Rang.NINE),
    SPADE_EIGTH(Suit.SPADE, Rang.EIGTH),
    SPADE_SEVEN(Suit.SPADE, Rang.SEVEN),
    SPADE_SIX(Suit.SPADE, Rang.SIX),
    SPADE_FIVE(Suit.SPADE, Rang.FIVE),
    SPADE_FOUR(Suit.SPADE, Rang.FOUR),
    SPADE_THREE(Suit.SPADE, Rang.THREE),
    SPADE_TWO(Suit.SPADE, Rang.TWO),
    HEART_ACE(Suit.HEART, Rang.ACE, 4),
    HEART_KING(Suit.HEART, Rang.KING, 3),
    HEART_QUEEN(Suit.HEART, Rang.QUEEN, 2),
    HEART_JACK(Suit.HEART, Rang.JACK, 1),
    HEART_TEN(Suit.HEART, Rang.TEN),
    HEART_NINE(Suit.HEART, Rang.NINE),
    HEART_EIGTH(Suit.HEART, Rang.EIGTH),
    HEART_SEVEN(Suit.HEART, Rang.SEVEN),
    HEART_SIX(Suit.HEART, Rang.SIX),
    HEART_FIVE(Suit.HEART, Rang.FIVE),
    HEART_FOUR(Suit.HEART, Rang.FOUR),
    HEART_THREE(Suit.HEART, Rang.THREE),
    HEART_TWO(Suit.HEART, Rang.TWO),
    DIAMOND_ACE(Suit.DIAMOND, Rang.ACE, 4),
    DIAMOND_KING(Suit.DIAMOND, Rang.KING, 3),
    DIAMOND_QUEEN(Suit.DIAMOND, Rang.QUEEN, 2),
    DIAMOND_JACK(Suit.DIAMOND, Rang.JACK, 1),
    DIAMOND_TEN(Suit.DIAMOND, Rang.TEN),
    DIAMOND_NINE(Suit.DIAMOND, Rang.NINE),
    DIAMOND_EIGTH(Suit.DIAMOND, Rang.EIGTH),
    DIAMOND_SEVEN(Suit.DIAMOND, Rang.SEVEN),
    DIAMOND_SIX(Suit.DIAMOND, Rang.SIX),
    DIAMOND_FIVE(Suit.DIAMOND, Rang.FIVE),
    DIAMOND_FOUR(Suit.DIAMOND, Rang.FOUR),
    DIAMOND_THREE(Suit.DIAMOND, Rang.THREE),
    DIAMOND_TWO(Suit.DIAMOND, Rang.TWO),
    CLUB_ACE(Suit.CLUB, Rang.ACE, 4),
    CLUB_KING(Suit.CLUB, Rang.KING, 3),
    CLUB_QUEEN(Suit.CLUB, Rang.QUEEN, 2),
    CLUB_JACK(Suit.CLUB, Rang.JACK, 1),
    CLUB_TEN(Suit.CLUB, Rang.TEN),
    CLUB_NINE(Suit.CLUB, Rang.NINE),
    CLUB_EIGTH(Suit.CLUB, Rang.EIGTH),
    CLUB_SEVEN(Suit.CLUB, Rang.SEVEN),
    CLUB_SIX(Suit.CLUB, Rang.SIX),
    CLUB_FIVE(Suit.CLUB, Rang.FIVE),
    CLUB_FOUR(Suit.CLUB, Rang.FOUR),
    CLUB_THREE(Suit.CLUB, Rang.THREE),
    CLUB_TWO(Suit.CLUB, Rang.TWO);

    static {
        for (int i = 0; i < values().length; i++) {
            values()[i].id = i;
        }
    }

    public static Card get(int cardId) {
        return values()[cardId];
    }

    public static Card[] values(Suit suit) {
        if (suit == null)
            throw new IllegalArgumentException();

        switch (suit) {
            case CLUB:
                return new Card[]{CLUB_ACE, CLUB_KING, CLUB_QUEEN, CLUB_JACK, CLUB_TEN, CLUB_NINE, CLUB_EIGTH, CLUB_SEVEN, CLUB_SIX, CLUB_FIVE, CLUB_FOUR, CLUB_THREE, CLUB_TWO};
            case DIAMOND:
                return new Card[]{DIAMOND_ACE, DIAMOND_KING, DIAMOND_QUEEN, DIAMOND_JACK, DIAMOND_TEN, DIAMOND_NINE, DIAMOND_EIGTH, DIAMOND_SEVEN, DIAMOND_SIX, DIAMOND_FIVE, DIAMOND_FOUR, DIAMOND_THREE, DIAMOND_TWO};
            case HEART:
                return new Card[]{HEART_ACE, HEART_KING, HEART_QUEEN, HEART_JACK, HEART_TEN, HEART_NINE, HEART_EIGTH, HEART_SEVEN, HEART_SIX, HEART_FIVE, HEART_FOUR, HEART_THREE, HEART_TWO};
            case SPADE:
                return new Card[]{SPADE_ACE, SPADE_KING, SPADE_QUEEN, SPADE_JACK, SPADE_TEN, SPADE_NINE, SPADE_EIGTH, SPADE_SEVEN, SPADE_SIX, SPADE_FIVE, SPADE_FOUR, SPADE_THREE, SPADE_TWO};
            default:
                throw new RuntimeException("Unknow suit");
        }
    }


    public enum Rang {
        ACE("A"), KING("K"), QUEEN("Q"), JACK("J"), TEN("T"), NINE("9"),
        EIGTH("8"), SEVEN("7"), SIX("6"), FIVE("5"), FOUR("4"), THREE("3"), TWO("2");


        private String ts;

        Rang(String ts) {
            this.ts = ts;
        }

        @Override
        public String toString() {
            return ts;
        }
    }

    private Suit suit;
    private Rang rang;
    private int hcp = 0;
    private int id;

    private Card(Suit suit, Rang rang) {
        this(suit, rang, 0);
    }

    private Card(Suit suit, Rang rang, int hcp) {
        this.suit = suit;
        this.rang = rang;
        this.hcp = hcp;
    }

    /**
     * Id of card in range 0 -> 51
     *
     * @return id of card
     */
    public int getId() {
        return id;
    }

    public Suit getSuit() {
        return suit;
    }

    public int getHcp() {
        return hcp;
    }

    public Rang getRang() {
        return rang;
    }

    public boolean isHonor() {
        return (rang == Rang.ACE || rang == Rang.KING || rang == Rang.QUEEN || rang == Rang.JACK);
    }

    @Override
    public String toString() {
        switch (suit) {
            case SPADE:
                return "S"+rang.toString();
            case HEART:
                return "H"+rang.toString();
            case DIAMOND:
                return "D"+rang.toString();
            case CLUB:
                return "C"+rang.toString();
        }
        return "";
    }
}
